package ru.papergames.utils.helpers
{
	import ru.papergames.model.vo.PositionVO;
	
	public final class MapHelper
	{
		/**
		 * Makes path
		 *  
		 * 
		 * */
		public static function make_path(from:PositionVO, dest:PositionVO, mapWidth:uint, mapHeight:uint, obstacles:Array = null):Array {
			var newPos:Object, i:int, j:int;
			var cells:Array = [];
			var moving_path:Array = [];
			
			if ((from.x == dest.x) && (from.y == dest.y)) {
				return [];
			}
			
			for (i = 0; i < mapWidth; i++) {
				var col:Array = [];
				for (j=0; j < mapHeight; j++) {
					col.push(0);
				}
				cells.push(col);
			}
			
			//filling obstacles
			if (obstacles) {
				for each (var obstaclePos:PositionVO in obstacles) {
					cells[obstaclePos.x][obstaclePos.y] = 100;
				}
			}
			
			//if dest point in obstacle - return
			if (cells[dest.x][dest.y] != 0) return moving_path;
			
			
			var found:Boolean = false;
			var noWay:Boolean = false;
			var pts:Array = []
			pts[0] = []
			pts[0][0] = {}
			pts[0][0].x = from.x;
			pts[0][0].y = from.y;
			pts[0][0].p = null;
			var cc:uint = 0;
			var p:Object = null;
			cells[from.x][from.y] = 100;
			//
			var paths:Array = [[-1, 0], [1, 0],[0, -1], [0, 1], [-1, -1],[1, -1], [-1, 1], [1, 1]];
			while (!found && !noWay) {
				noWay = true;
				pts[cc+1] = [];
				//
				for (var np:uint = 0; np<pts[cc].length; np++) {
					p = pts[cc][np];
					for (var k:uint = 0; k<paths.length; k++) {
						i = paths[k][0];
						j = paths[k][1];
						if (p.x+i<0 || p.x+i>=cells.length || p.y+j<0 || p.y+j>=cells[0].length) {
							continue;
						}
						// is path found
						if (p.x+i == dest.x && p.y+j == dest.y) {
							noWay = false;
							found = true;
							break;
						}
						// is cell free from 4 personages or not-passed-trough anturages
						if (cells[p.x+i][p.y+j]<100) {
							noWay = false;
							newPos = {};
							newPos.x = p.x+i;
							newPos.y = p.y+j;
							newPos.p = p;
							pts[cc+1][pts[cc+1].length] = newPos;
							cells[p.x+i][p.y+j] = 100;
						}
					}
					if (found) {
						break;
					}
				}
				cc++;
			}
			
			//filling path array from calculated minimal-path-tree object			
			if (!noWay) {
				moving_path[0] = new PositionVO(dest.x, dest.y);
				
				while (p.p) {
					moving_path.unshift(new PositionVO(p.x, p.y));
					p = p.p;
				}
			}
			
			return moving_path;
		}
		
		/**
		 * Calculate direction code for vector 
		 * 
		 * */
		public static function getDirectionCode(nx:Number, ny:Number):uint {
			var direction:uint;
			
			//normalizing vector
			var maxval:Number = (Math.abs(nx)>Math.abs(ny)) ? Math.abs(nx) : Math.abs(ny);
			nx = Math.round(nx/maxval);
			ny = Math.round(ny/maxval);
			//
			var rez:int = 3*nx+ny;
			switch (rez) {
				case -1 :
					direction = 1;
					break;
				case 2 :
					direction = 2;
					break;
				case 3 :
					direction = 3;
					break;
				case 4 :
					direction = 4;
					break;
				case 1 :
					direction = 5;
					break;
				case -2 :
					direction = 6;
					break;
				case -3 :
					direction = 7;
					break;
				case -4 :
					direction = 8;
					break;
				default :
					direction = 0;
					break;
			}
			
			return direction;
		}

	}
}